package com.wfg.spring.springRegistrar.FactoryBean;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;

import java.util.HashSet;
import java.util.Set;

/**
 * @author: 王富贵
 * @description: 自定义ClassPathBeanDefinition扫描器
 * @createTime: 2023/11/17 20:32
 */
public class WfgClassPathBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {
    /**
     * 默认构造器，扫描指定注解
     * @param registry
     */
    public WfgClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry,HashSet<String> annotationNames) {
        super(registry, false);
        for (String annotationClassName : annotationNames) {
            this.addIncludeFilter((metadataReader, metadataReaderFactory) ->
                    metadataReader.getAnnotationMetadata().hasAnnotation(annotationClassName));
        }
    }

    /**
     * 重写是否是候选组件扫描规则，当是接口时扫描
     *
     * @param beanDefinition the bean definition to check
     * @return
     */
    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        return beanDefinition.getMetadata().isInterface();
    }

    @Override
    public Set<BeanDefinition> findCandidateComponents(String basePackage) {
        Set<BeanDefinition> candidateComponents = super.findCandidateComponents(basePackage);
        Set<BeanDefinition> newBeanDefinition = new HashSet<>();
        for (BeanDefinition beanDefinition : candidateComponents) {
            AbstractBeanDefinition proxyBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SelectMapperFactoryBean.class)
                    .addConstructorArgValue(beanDefinition.getBeanClassName())
                    .getBeanDefinition();
            newBeanDefinition.add(proxyBeanDefinition);
        }
        return newBeanDefinition;
    }
}
